package com.fishery.customization.dao;

import com.fishery.customization.dao.reposity.BaseDao;
import com.fishery.customization.entity.OneLevelLabel;
import com.fishery.customization.entity.UserLabel;
import com.fishery.customization.util.DataUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

@Repository
public class UserLabelDao extends BaseDao<UserLabel> {


	@Autowired
	private LabelDao labelDao;

	@Autowired
	private ExecutorService threadPool;

	/**
	 * 通过用户ID获取用户自定义后的Json标签
	 *
	 * @param userId
	 * @return
	 */
	public String findCustomizedLabelsOfUserByUserId(String userId) {
		HashMap<String, Object> fields = new HashMap<>(2);
		fields.put("customized_labels", 1);
		fields.put("_id", 0);
		return mongoOperations.findOne(getBasicQuery("user_id", userId, fields),
				String.class, getCollectionName());
	}


	/**
	 * 保存或修改用户自定义标签
	 *
	 * @param userLabel
	 * @return
	 */
	public long upsertLabelsByUserId(UserLabel userLabel) {
		Map<String, Object> queryMap = new HashMap<>(3);
		queryMap.put("user_id", userLabel.getUserId());
		queryMap.put("role", userLabel.getRole());
		queryMap.put("base_id", userLabel.getBaseId());
		return mongoOperations.upsert(getBasicQuery(queryMap), Update.update("customized_labels",
				userLabel.getCustomizedLabels()), getCollectionName()).wasAcknowledged() ? 1 : 0;
	}

	/**
	 * 通过用户ID删除用户自定义标签
	 *
	 * @param userId
	 * @return
	 */
	public long deleteLabelsByUserId(String userId) {
		return mongoOperations.remove(Query.query(Criteria.where("user_id").is(userId)),
				getCollectionName()).getDeletedCount();
	}

	/**
	 * 通过基地ID修改基地角色名
	 *
	 * @param baseId
	 * @param oldName
	 * @param newName
	 * @return
	 */
	public long updateBaseRoleNameByBaseId(String baseId, String oldName, String newName) {
		Map<String, Object> queryMap = new HashMap<>(2);
		queryMap.put("base_id", baseId);
		queryMap.put("role", oldName);
		return mongoOperations.updateMulti(getBasicQuery(queryMap),
				Update.update("role", newName), getCollectionName()).getModifiedCount();
	}

	/**
	 * 通过基地ID、角色获取所有用户标签
	 *
	 * @param baseId
	 * @param role
	 * @return
	 */
	public List<UserLabel> findUserLabelsByBaseIdAndRole(String baseId, String role) {
		return mongoOperations.find(Query.query(Criteria.where("base_id").is(baseId).and("role").is(role)),
				UserLabel.class, getCollectionName());
	}

	/**
	 * 通过基地Id、角色对用户自定义标签进行修改
	 *
	 * @param baseId
	 * @param role
	 * @param addOneLevelLabels
	 * @param deleteOneLevelLabels
	 * @return
	 */
	public long queryAndUpdate(String baseId, String role, Collection<OneLevelLabel> addOneLevelLabels, Collection<OneLevelLabel> deleteOneLevelLabels) {
		if ((addOneLevelLabels == null || addOneLevelLabels.isEmpty())
				&& (deleteOneLevelLabels == null || deleteOneLevelLabels.isEmpty())) {
			return 1;
		}
		// 查询mongo里面原本该基地角色对应的用户自定义标签标签对象
		List<UserLabel> oldUserLabels = findUserLabelsByBaseIdAndRole(baseId, role);
		CompletableFuture.runAsync(() -> {
			for (UserLabel oldUserLabel : oldUserLabels) {
				// 查询所有原先的一级标签集合
				List<OneLevelLabel> oldOneLevelLabels = oldUserLabel.getCustomizedLabels();
				// 在原先的基础上删除二级标签
				if (deleteOneLevelLabels != null && !deleteOneLevelLabels.isEmpty()) {
					DataUtil.exceptSameLabels(deleteOneLevelLabels, oldOneLevelLabels);
				}
				// 在原先的基础上去增加二级标签
				if (addOneLevelLabels != null && !addOneLevelLabels.isEmpty()) {
					for (OneLevelLabel oneLevelLabel : addOneLevelLabels) {
						boolean hasOperated = false;
						for (OneLevelLabel oldOneLevelLabel : oldOneLevelLabels) {
							if (hasOperated || oneLevelLabel.getChildren().isEmpty()) {
								break;
							}
							if (oneLevelLabel.getName().equals(oldOneLevelLabel.getName())) {
								oldOneLevelLabel.getChildren().addAll(oneLevelLabel.getChildren());
								hasOperated = true;
							}
						}
						if (!hasOperated && !oneLevelLabel.getChildren().isEmpty()) {
							oldOneLevelLabels.add(oneLevelLabel);
						}
					}
				}
				// 修改数据
				mongoOperations.updateFirst(Query.query(Criteria.where(getIdName())
								.is(getIdValue(oldUserLabel))), Update.update("customized_labels", oldOneLevelLabels),
						UserLabel.class, getCollectionName());
			}
		});
		return 1;
	}

	/**
	 * 通过基地Id、排除角色名对基地其它用户自定义标签进行修改
	 *
	 * @param baseId
	 * @param exceptRole
	 * @param addOneLevelLabels
	 * @param deleteOneLevelLabels
	 * @return
	 */
	public long queryAndUpdateOthers(String baseId, String exceptRole, Collection<OneLevelLabel> addOneLevelLabels, Collection<OneLevelLabel> deleteOneLevelLabels) {
		if ((addOneLevelLabels == null || addOneLevelLabels.isEmpty())
				&& (deleteOneLevelLabels == null || deleteOneLevelLabels.isEmpty())) {
			return 1;
		}
		// 查询该基地有哪些其它角色（除了exceptRole）
		List<String> roles = labelDao.findOtherRoles(baseId, exceptRole);
		if (roles != null && !roles.isEmpty()) {
			// 对这些角色进行拓展
			roles.forEach(role -> queryAndUpdate(baseId, role, addOneLevelLabels, deleteOneLevelLabels));
		}
		return 1;
	}
}
